/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package cn.ac.iie.di.wb.picmover.send;

import cn.ac.iie.di.datadock.rdata.exchange.client.core.REFieldType;
import cn.ac.iie.di.datadock.rdata.exchange.client.exception.RESessionException;
import cn.ac.iie.di.datadock.rdata.exchange.client.v1.session.RESendSession;
import cn.ac.iie.di.wb.picmover.handler.*;
import cn.ac.iie.di.wb.picmover.send.PicSendHandler.SessionPool;
import cn.ac.iie.di.wb.picmover.util.GlobalParameters;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;

/**
 *
 * @author Administrator
 */
public class PicSendThreadPoolTask implements Runnable {

    static private final Logger logger = Logger.getLogger(PicSendThreadPoolTask.class.getName());
    private final Message list;
    private final SessionPool pool;

    public PicSendThreadPoolTask(Message list, SessionPool pool) {
        this.list = list;
        this.pool = pool;
    }

    @Override
    public void run() {
        logger.info("get " + list.getData().size() + " datas form picSendHandlerQueue!");
        RESendSession session = null;
        long starttime = System.currentTimeMillis() / 1000;
        long start = System.currentTimeMillis() / 1000;
        int colid = 0;
        try {
            session = pool.borrowSession();

            List<Object[]> datalist = list.getData();
            String[] colNames = list.getColNames();
            REFieldType[] types = list.getTypes();

            for (int i = 0; i < colNames.length; i++) {
                if (colNames[i].equals(GlobalParameters.addColName)) {
                    colid = i;
                    break;
                }
            }

            for (Object[] obj : datalist) {
                for (int j = 0; j < obj.length; j++) {
                    try {
                        if (j != colid) {
                            switch (types[j]) {
                                case String:
                                    session.setString(colNames[j], String.valueOf(obj[j].toString()));
                                    break;
                                case Int:
                                    session.setInt(colNames[j], Integer.valueOf(obj[j].toString()));
                                    break;
                                case Long:
                                    session.setLong(colNames[j], Long.valueOf(obj[j].toString()));
                                    break;
                                case Float:
                                    session.setFloat(colNames[j], Float.valueOf(obj[j].toString()));
                                    break;
                                case Double:
                                    session.setDouble(colNames[j], Double.valueOf(obj[j].toString()));
                                    break;
                                case Binary:
                                    session.setBinary(colNames[j], obj[j].toString().getBytes());
                                    break;
                                case Longs:
                                    session.setLongs(colNames[j], (long[]) obj[j]);
                                    break;
                                case Ints:
                                    session.setInts(colNames[j], (int[]) obj[j]);
                                    break;
                                case Strings:
                                    session.setStrings(colNames[j], (String[]) obj[j]);
                                    break;
                                case Boolean:
                                    session.setBoolean(colNames[j], (boolean) obj[j]);
                                    break;
                                case Booleans:
                                    session.setBooleans(colNames[j], (boolean[]) obj[j]);
                                    break;
                                case Struct:
                                    session.setStruct(colNames[j], (Map) obj[j]);
                                    break;
                                case Structs:
                                    session.setStructs(colNames[j], (Map[]) obj[j]);
                                    break;
                                default:
                                    logger.warn(colNames[j] + ": (type)" + types[j] + " do not recognize this type!");
                            }
                        }
                    } catch (RESessionException | NumberFormatException ex) {
                        logger.error(ex, ex);
                    } catch (Exception ex) {
                        logger.error(ex, ex);
                    }
                }
                try {
                    session.add();
                } catch (Exception e) {
                    sendMSG(session);
                    session.add();
                }

                if (System.currentTimeMillis() / 1000 - starttime > GlobalParameters.timeout) {
                    starttime = System.currentTimeMillis() / 1000;
                    sendMSG(session);
                    logger.info("timeout.");
                }
            }
            sendMSG(session);
            logger.info("flush all results " + datalist.size() + " and use time " + (System.currentTimeMillis() / 1000 - start) + " s");
        } catch (Exception ex) {
            logger.error("setSession error, cause " + ex.getMessage(), ex);
        } finally {
            if (session != null) {
                pool.returnSession(session);
            }
        }
    }

    public void sendMSG(RESendSession session) {
        while (true) {
            try {
                logger.info("flush...");
                session.flush();
                break;
            } catch (Exception ex) {
                logger.info("what's up buddy ? how's it going ?" + ex, ex);
            }
        }
    }

}
